package sniff.diller;

import jpcap.packet.IPPacket;
import jpcap.packet.Packet;
import sniff.pack.CommonIPChildPacket;
import sniff.pack.MyIPv4Packet;
import util.ByteUtil;

public class IPv4PacketDiller {

	public static MyIPv4Packet dill(Packet pack) {
		IPPacket ipPack = (IPPacket) pack;
		byte[] head = ipPack.header;
		byte[] data = ipPack.data;
		int startIndex = 14;
		CommonHeadDiller hd = new CommonHeadDiller(head);
		String sourceMAC = hd.getSourceMAC();
		String destinationMAC = hd.getDestinationMAC();
		String type = hd.getType();

		String version = "IPV4";
		if (ByteUtil.getFourBit(head[startIndex], false) != 4) {
			version = "error";
		}
		int headLen = ByteUtil.getFourBit(head[startIndex], true) * 4;
		String ds = ByteUtil.byteToHexString(head[startIndex + 1]);
		int totalLen = ByteUtil.unionByte(head[startIndex + 2], head[startIndex + 3]);
		String id = "0x" + ByteUtil.byteToHexString(head[startIndex + 4])
				+ ByteUtil.byteToHexString(head[startIndex + 5]);
		int mf = ByteUtil.getIndexBit(head[startIndex + 6], 5);
		int df = ByteUtil.getIndexBit(head[startIndex + 6], 6);
		int fragmentOffset = getFragmentOffset(head[startIndex + 6], head[startIndex + 7]);
		int timeToLive = ByteUtil.byteToInt(head[startIndex + 8]);
		CommonIPChildPacket childPacket = null;
		String protocol = "IPV4";
		switch (ByteUtil.byteToInt(head[startIndex + 9])) {
		case 1:
			protocol = "ICMP";
			childPacket=ICMPPacketDiller.dill(pack);
			break;
		case 2:
			protocol = "IGMP";
			break;
		case 6:
			protocol = "TCP";
			childPacket = TCPPacketDiller.dill(pack);
			break;
		case 8:
			protocol = "EGP";
			break;
		case 9:
			protocol = "IGP";
			break;
		case 17:
			protocol = "UDP";
			childPacket =UDPPacketDiller.dill(pack);
			break;
		case 41:
			protocol = "IPV6";
			break;
		case 50:
			protocol = "ESP";
			break;
		case 89:
			protocol = "OSPF";
			childPacket = OSPFPacketDiller.dill(pack);
			break;
		default:
			break;
		}

		String headerCheckNum = "0x" + ByteUtil.byteToHexString(head[startIndex + 10])
				+ ByteUtil.byteToHexString(head[startIndex + 11]);

		String sourceIP = ByteUtil.byteToInt(head[startIndex + 12]) + "." + ByteUtil.byteToInt(head[startIndex + 13])
				+ "." + ByteUtil.byteToInt(head[startIndex + 14]) + "." + ByteUtil.byteToInt(head[startIndex + 15]);
		String destinationIP = ByteUtil.byteToInt(head[startIndex + 16]) + "."
				+ ByteUtil.byteToInt(head[startIndex + 17]) + "." + ByteUtil.byteToInt(head[startIndex + 18]) + "."
				+ ByteUtil.byteToInt(head[startIndex + 19]);
		String info = "";
		MyIPv4Packet myIpPack = new MyIPv4Packet(sourceMAC, destinationMAC, type, totalLen, info, head, data, version,
				headLen, ds, id, mf, df, fragmentOffset, timeToLive, protocol, headerCheckNum, sourceIP, destinationIP);
		myIpPack.setChildPacket(childPacket);

		return myIpPack;
	}

	private static int getFragmentOffset(byte b1, byte b2) {
		int b = ByteUtil.unionByte(b1, b2);
		return b & 0x1fff;
	}

}
